using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace PassTheBomb
{
    public partial class Mainform : Form
    {
        private FMOD.System FModSystem = null;
        private FMOD.Channel FModChannel = null;
        private FMOD.Sound BackgroundMusic = null;
        private FMOD.Sound BangSound = null;
        private Random Rnd = new Random();

        private int[] LetterFrequency = new int[] { 2, 9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1 };
        private char[] Letters = new char[] { ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

        private string CurLetters = null;
        private bool Paused = false;

        public Mainform()
        {
            InitializeComponent();

            FMOD.Factory.System_Create(ref FModSystem);
            uint version = 0;
            FModSystem.getVersion(ref version);
            if (version < FMOD.VERSION.number)
            {
                MessageBox.Show("Error!  You are using an old version of FMOD (" + version.ToString("X") + ").  This program requires " + FMOD.VERSION.number.ToString("X") + ".");
                Application.Exit();
            }
            FModSystem.init(32, FMOD.INITFLAG.NORMAL, (IntPtr) null);

            FModSystem.createSound("Bang.ogg", FMOD.MODE.LOOP_OFF, ref BangSound);
            FModSystem.createSound("Ticking.ogg", FMOD.MODE.LOOP_NORMAL, ref BackgroundMusic);
            BackgroundMusic.setLoopPoints(264506, FMOD.TIMEUNIT.PCM, 970139, FMOD.TIMEUNIT.PCM);
        }

        private void StartFModSound(FMOD.Sound snd, float volume, ref FMOD.Channel chn)
        {
            FMOD.CHANNELINDEX chIndex = FMOD.CHANNELINDEX.FREE;
            if (chn != null)
            {
                chn.stop();
                chIndex = FMOD.CHANNELINDEX.REUSE;
            }
            FModSystem.playSound(chIndex, snd, true, ref chn);
            chn.setVolume(volume);
            chn.setPaused(false);
        }

        private void BombTimer_Tick(object sender, EventArgs e)
        {
            StartFModSound(BangSound, 1, ref FModChannel);
            BombTimer.Enabled = false;
            CurLetters = null;
            MainPanel.Refresh();
        }

        private void IncvolTimer_Tick(object sender, EventArgs e)
        {
            int i = (int) IncvolTimer.Tag;
            i--;
            FModChannel.setVolume((float) (40 - i) / 40);
            if (i == 0)
                IncvolTimer.Enabled = false;
            else
                IncvolTimer.Tag = i;
        }

        private void Mainform_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13 || e.KeyChar == 'q')
            {
                BombTimer.Enabled = false;
                IncvolTimer.Enabled = false;
                LettersTimer.Enabled = false;
                CurLetters = null;
                MainPanel.Refresh();
                StartFModSound(BackgroundMusic, 0, ref FModChannel);
                BombTimer.Interval = Rnd.Next(14000, 64000);
                BombTimer.Enabled = true;
                IncvolTimer.Tag = 40;
                IncvolTimer.Enabled = true;
                LettersTimer.Enabled = true;
            }
            else if (e.KeyChar == 32 && FModChannel != null)
            {
                if (Paused)
                {
                    BombTimer.Interval = Rnd.Next(0, 30000);
                    BombTimer.Enabled = true;
                }
                else
                {
                    BombTimer.Enabled = false;
                }
                Paused = !Paused;
                FModChannel.setPaused(Paused);
                MainPanel.Refresh();
            }
        }

        private void LettersTimer_Tick(object sender, EventArgs e)
        {

            /* 
            //Single-letter

            do
            {
                CurLetters = "" + RandomLetter();
                CurLetters = CurLetters.Trim();
            } while (CurLetters.Length == 0);

            for (int i = 0; i < LetterFrequency.Length; i++)
                if (Letters[i] == CurLetters[0])
                    LetterFrequency[i] = 0;
             * */

            // Two-letter
            CurLetters = "" + RandomLetter() + RandomLetter();
            CurLetters = CurLetters.Trim();

            MainPanel.Refresh();
            LettersTimer.Enabled = false;
        }

        private char RandomLetter()
        {
            int Total = 0;
            foreach (int i in LetterFrequency)
                Total += i;
            int Choice = Rnd.Next(0, Total);
            int Index = 0;
            while (Choice >= LetterFrequency[Index])
            {
                Choice -= LetterFrequency[Index];
                Index++;
            }
            return Letters[Index];
        }

        private void MainPanel_PaintBuffer(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(Color.Black);
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
            e.Graphics.DrawString(CurLetters, new Font("Verdana", 480, FontStyle.Bold), new SolidBrush(Color.White), ClientSize.Width / 2, ClientSize.Height / 2,
                new StringFormat()
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                });
            if (Paused)
            {
                GraphicsPath p = new GraphicsPath();
                p.AddString("PAUSED", new FontFamily("Verdana"), 0, 384, new Point(ClientSize.Width / 2, ClientSize.Height / 2), new StringFormat()
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                });
                p.Widen(new Pen(Color.Black, 10));
                e.Graphics.FillPath(new SolidBrush(Color.Black), p);
                p = new GraphicsPath();
                p.AddString("PAUSED", new FontFamily("Verdana"), 0, 384, new Point(ClientSize.Width / 2, ClientSize.Height / 2), new StringFormat()
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                });
                e.Graphics.FillPath(new SolidBrush(Color.Red), p);
            }
        }
    }
}
